Amazon TimestreamとIoT Core RuleアクションをCloudFormationで作成する
CloudFormationを使って、Amazon Timestreamを作ってみました。 IoT Coreのルールアクションも作成し、とあるMQTTトピックに来たデータをAmazon Timestreamに格納する仕組みです。
CloudFormationテンプレートの作成
作成したCloudFormationテンプレートは下記です。IoT Coreで受け取ったメッセージをAmazon Timestreamに格納しています。
AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Timestream Sample Resources: IoTDataTimestreamDatabase: Type: AWS::Timestream::Database Properties: DatabaseName: CfnSampleDatabase IoTDataTimestreamTable: Type: AWS::Timestream::Table Properties: DatabaseName: !Ref IoTDataTimestreamDatabase RetentionProperties: MemoryStoreRetentionPeriodInHours: 24 MagneticStoreRetentionPeriodInDays: 7 TableName: iot-data-sample-table IoTDataRule: Type: AWS::IoT::TopicRule Properties: TopicRulePayload: RuleDisabled: false Actions: - Timestream: RoleArn: !GetAtt IoTDataRuleRole.Arn DatabaseName: !Ref IoTDataTimestreamDatabase TableName: !Select [1, !Split [ "|", !Ref IoTDataTimestreamTable ] ] Dimensions: - Name: deviceId Value: ${topic(2)} Timestamp: Unit: MILLISECONDS Value: ${timestamp} Sql: SELECT temperature FROM 'sample/+/temperature' IoTDataRuleRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: iot.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: iot-data-timestream-rule-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: timestream:WriteRecords Resource: !GetAtt IoTDataTimestreamTable.Arn - Effect: Allow Action: timestream:DescribeEndpoints Resource: "*"
テーブル名は直接参照できないので加工する
AWS::Timestream::Table
を!Ref
で参照すると、次のような値が得られます。
- CfnSampleDatabase|iot-data-sample-table
- データベース名|テーブル名
IoT Ruleアクションにはテーブル名のみを渡すので、!Split
で分割し、!Select
でテーブル名のみを取得しています。
- !Select [1, !Split [ "|", !Ref IoTDataTimestreamTable ] ]
timestampの指定について補足
CloudFormationのドキュメントを見ても、Actions.Timestream.Timestamp
のUnit
とValue
の設定すべき内容が不明ですが、下記ドキュメントを参考にしてください。
Unit
に指定する内容- SECONDS
- MILLISECONDS (default)
- MICROSECONDS
- NANOSECONDS
Value
に指定する内容- Unixtime
- time_to_epoch()で変換した値
- デバイスが送信した値
- timestamp() で取得した値
- Unixtime
Actions.Timestream.Timestamp
自体が無い場合は、処理された時刻がAWSによって付与されます。
デプロイする
まだ東京リージョンには来ていないため、us-west-2
にデプロイします。
aws cloudformation deploy \ --region us-west-2 \ --template-file timestream.yaml \ --capabilities CAPABILITY_NAMED_IAM \ --stack-name AmazonTimestreamSampleStack
動作確認
データをPublishする
- トピック: sample/d0001/temperature
{ "temperature": 12.3, "timestamp": 1621918928959 }
{ "temperature": 22.2, "timestamp": 1621928216789 }
Amazon Timestreamを確認する
10件のデータを取得してみます。
SELECT * FROM "CfnSampleDatabase"."iot-data-sample-table" ORDER BY time DESC LIMIT 10
バッチリ格納されていました!!
time
は、IoT Ruleアクションで指定したとおり、「JSONデータ内のタイムスタンプ」が格納されています。
さいごに
Amazon TimestreamがGAした当初は、CloudFormationで「IoT Coreのルールアクション(to Amazon Timestream)」が非対応でしたが、いつの間にか対応していました。早く東京リージョンに来てほしいです。